
package com.xiaoma.myaudience.util.task;

import java.lang.ref.WeakReference;

import android.content.Context;

import com.xiaoma.myaudience.util.HttpUtils;
import com.xiaoma.myaudience.util.http.AndroidHttpClient;

/**
 * 包含各种异步获取数据任务.
 * 
 * @author wjying
 */
public abstract class BaseDataAsyncTask<Params, Progress, Result> extends
     NeteaseAsyncTask<Params, Progress, Result> {

    /**
     * ************************以上为任务标识*********************************.
     */
   
    protected static final int CMD_CALLBACK_CANCEL = 0;

    protected static final int CMD_CALLBACK_UPDATE = 1;

    protected static final int CMD_CALLBACK_PRE_EXECUTE = 2;

    protected static final int CMD_CALLBACK_POST_EXECUTE = 3;

    protected Context mContext;

    private WeakReference<DataAsyncCallback> mCallback;

    private int mWhatTask;

    private AndroidHttpClient mHttpClient;

    /**
     * 构造方法.
     * 
     * @param context
     * @param what 表示的是由哪个任务 如 {@link #TASK_FIRST_PAGE_INFO}
     * @param callback
     */
    protected BaseDataAsyncTask(Context context, int what, DataAsyncCallback callback) {
        mContext = context;
        mWhatTask = what;
        mCallback = new WeakReference<DataAsyncCallback>(callback);
    }
    
    /**
     * 设置Callback
     * 
     * @param callback
     */
    public void setCallback(DataAsyncCallback callback) {
        if (callback == null) {
            mCallback = null;
        } else {
            mCallback = new WeakReference<DataAsyncCallback>(callback);
        }
    }

    /**
     * 返回AndroidHttpClient. <br/>
     * 如果调用了这个方法注意需要调用{@link #closeHttpClient}<br/>
     * 
     * @return
     */
    public AndroidHttpClient getHttpClient() {
        if (mHttpClient == null) {
            mHttpClient = HttpUtils.getAndroidHttpClient(mContext);
        }
        return mHttpClient;
    }

    /**
     * 关闭HttpClient.
     */
    public void closeHttpClient() {
        if (mHttpClient != null) {
            mHttpClient.close();
            mHttpClient = null;
        }
    }

    /**
     * 取消任务.
     * 
     * @param mayInterruptIfRunning
     * @param clearCallback 如果是true,将callback置null
     */
    public void cancel(boolean mayInterruptIfRunning, boolean clearCallback) {
        if (clearCallback) {
            mCallback = null;
        }

        mContext = null;
        
        if (getStatus() != Status.FINISHED) {
            super.cancel(mayInterruptIfRunning);
        }
    }

    /**
     * 由子类回调callback.<br/>
     * 
     * @param cmd {@link CMD_CALLBACK_CANCEL} {@link CMD_CALLBACK_CANCEL}
     *            {@link CMD_CALLBACK_CANCEL} {@link CMD_CALLBACK_CANCEL} 其中一个
     * @param o
     */
    protected void callback(int cmd, Object o) {
        DataAsyncCallback callback = mCallback == null ? null : mCallback.get();
        if (callback != null) {
            switch (cmd) {
                case CMD_CALLBACK_CANCEL:
                    callback.onCancelled(mWhatTask);
                    break;
                case CMD_CALLBACK_UPDATE:
                    callback.onProgressUpdate(mWhatTask, o);
                    break;
                case CMD_CALLBACK_PRE_EXECUTE:
                    callback.onPreExecute(mWhatTask);
                    break;
                case CMD_CALLBACK_POST_EXECUTE:
                    callback.onPostExecute(mWhatTask, o);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    protected void onCancelled() {
        callback(CMD_CALLBACK_CANCEL, null);
    }

    @Override
    protected void onPreExecute() {
        callback(CMD_CALLBACK_PRE_EXECUTE, null);
    }

    @Override
    protected void onPostExecute(Result result) {
        callback(CMD_CALLBACK_POST_EXECUTE, result);
    }

    @Override
    protected void onProgressUpdate(Progress... values) {
        callback(CMD_CALLBACK_UPDATE, values);
    }

    /**
     * 数据获取回调. <br/>
     * 各个方法参考 {@link #AsyncTask}的回调方法 <br/>
     * 其中what参数表示的是由哪个方法回调
     * 
     * @author wjying
     */
    public interface DataAsyncCallback {
        public void onCancelled(int what);

        public void onPreExecute(int what);

        public void onPostExecute(int what, Object o);

        public void onProgressUpdate(int what, Object o);

    }
}
